package com.yourenbang.lingyun.transaction.web.service.impl.migrate;

import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.BizCodeMessages;
import com.yourenbang.lingyun.constants.enums.ChannelIdEnums;
import com.yourenbang.lingyun.constants.enums.PayTransactionStatusEnum;
import com.yourenbang.lingyun.constants.enums.PayTransactionWithdrawalStatusEnum;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.core.exception.BizRuntimeException;
import com.yourenbang.lingyun.core.util.BizAssertUtils;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.redis.RedisUtils;
import com.yourenbang.lingyun.domain.Merchant20;
import com.yourenbang.lingyun.domain.PayTransactionIndex;
import com.yourenbang.lingyun.domain.PayTransactionIndexExample;
import com.yourenbang.lingyun.mapper.Merchant20Mapper;
import com.yourenbang.lingyun.mapper.PayTransactionIndexMapper;
import com.yourenbang.lingyun.mapper.UserBaseExtMapper;
import com.yourenbang.lingyun.transaction.config.AcmTransactionParams;
import com.yourenbang.lingyun.transaction.mapper.TransactionPayTransactionMapper;
import com.yourenbang.lingyun.transaction.web.domain.dto.migrate.kuaishou.MigrateDTO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.KlksPayTransactionIndex;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.KlksPayTransactionPO;
import com.yourenbang.lingyun.transaction.web.domain.po.klks.PayWithdrawalPO;
import com.yourenbang.lingyun.transaction.web.service.migrate.PayTransactionMigrateService;
import com.yourenbang.lingyun.transaction.web.service.pay.TradeService;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service("payTransactionMigrateService")
public class PayTransactionMigrateServiceImpl extends AbstractMigrateService implements PayTransactionMigrateService {

    @Autowired
    private RedisUtils redis;
    @Autowired
    private UserBaseExtMapper userBaseExtMapper;
    @Autowired
    private Merchant20Mapper merchant20Mapper;
    @Autowired
    private TransactionPayTransactionMapper transactionPayTransactionMapper;
    @Autowired
    private PayTransactionIndexMapper payTransactionIndexMapper;
    @Autowired
    private AcmTransactionParams acmTransactionParams;
    @Autowired
    private TradeService tradeService;

    /**
     * 交易
     */
    @Override
    public void payTransaction(MigrateDTO dto) {
        if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_INSERT)){
            payTransactionInsert(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_UPDATE)){
            payTransactionUpdate(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_DELETE)){
            payTransactionDelete(dto);
        }else {
            KLog.error("[交易-考拉快收-数据同步]交易,不支持的数据操作入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
        }
    }

    /**
     * 交易插入
     * 必须参数：UserId，ProductType
     */
    private void payTransactionInsert(MigrateDTO dto){

        KlksPayTransactionPO klksPayTransaction = JSONObject.parseObject(dto.getData(), KlksPayTransactionPO.class);
        if(klksPayTransaction==null){
            KLog.error("[交易-考拉快收-数据同步]交易插入,数据解析空,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "数据解析空");
        }

        if (StringUtils.equals(klksPayTransaction.getProductType(),"06")){
            return;
        }
        if (!Objects.isNull(klksPayTransaction.getTransAmt())){
            if (klksPayTransaction.getTransAmt().compareTo(new BigDecimal("99999999.00")) > 0){
                return;
            }
        }

        if(StringUtils.isAnyBlank(klksPayTransaction.getUserId(),klksPayTransaction.getProductType())){
            KLog.error("[交易-考拉快收-数据同步]交易插入,缺失必须参数,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "缺失必须参数");
        }

        String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransaction.getUserId(), redis);
        if(StringUtils.isBlank(userBaseId)){
            KLog.error("[交易-考拉快收-数据同步]交易插入,未获取到凌云用户id,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
        }

        PayTransaction oldPayTran = transactionPayTransactionMapper.getByOrderNo(getTransTableIndex(userBaseId), klksPayTransaction.getOrderNo());
        if(oldPayTran != null){
            KLog.warn("[交易-考拉快收-数据同步]交易插入,已存在该数据,不作处理,入参:{}", dto.toJSON());
            return;
//            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "已存在该数据");
        }

        PayTransaction payTransaction = fmtPayTransactionData(klksPayTransaction, userBaseId);

        if (StringUtils.equalsIgnoreCase(payTransaction.getRemarks(), SUBTRACT_TRANS_FLAG)) {
            payTransaction.setProfitFlag(Boolean.FALSE);
            KLog.info("[交易-考拉快收-数据同步] - [payTransactionInsert] 扣减交易，不算分润，orderNo={}", payTransaction.getOrderNo());
        }

        int inCount = transactionPayTransactionMapper.insert(getTransTableIndex(userBaseId), payTransaction);
        BizAssertUtils.assertOne(inCount, "添加交易失败");
        //电签交易且计入分润发送分润mq
        if (acmTransactionParams.getProfitMqFlag()
                && payTransaction.getProfitFlag()
                && (ChannelIdEnums.epos.isEquals(payTransaction.getChannelId())
                    || ChannelIdEnums.epos_p30.isEquals(payTransaction.getChannelId())
                    || ChannelIdEnums.p35.isEquals(payTransaction.getChannelId()))) {
            tradeService.sendProfitPayTransactionMq(payTransaction);
        }
    }

    /**
     * 交易更新
     * 必须参数：UserId，OrderNo，ProductType
     */
    private void payTransactionUpdate(MigrateDTO dto){

        KlksPayTransactionPO klksPayTransaction = JSONObject.parseObject(dto.getData(), KlksPayTransactionPO.class);
        if(klksPayTransaction==null){
            KLog.error("[交易-考拉快收-数据同步]交易更新,数据解析空,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "数据解析空");
        }

        if (StringUtils.equals(klksPayTransaction.getProductType(),"06")){
            return;
        }
        if (!Objects.isNull(klksPayTransaction.getTransAmt())){
            if (klksPayTransaction.getTransAmt().compareTo(new BigDecimal("99999999.00")) > 0){
                return;
            }
        }

        if(StringUtils.isAnyBlank(klksPayTransaction.getUserId(), klksPayTransaction.getOrderNo(), klksPayTransaction.getProductType())){
            KLog.error("[交易-考拉快收-数据同步]交易更新,缺失必须参数,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "缺失必须参数");
        }

        String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransaction.getUserId(), redis);
        if(StringUtils.isBlank(userBaseId)){
            KLog.error("[交易-考拉快收-数据同步]交易更新,未获取到凌云用户id,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
        }

        PayTransaction oldPayTran = transactionPayTransactionMapper.getByOrderNo(getTransTableIndex(userBaseId), klksPayTransaction.getOrderNo());
        if(oldPayTran==null){
            KLog.warn("[交易-考拉快收-数据同步]交易更新,未获取到原交易,等待0.8秒重新查询,入参:{}", dto.toJSON());
            try {
                TimeUnit.MILLISECONDS.sleep(800);
            } catch (InterruptedException e) {
                log.error("交易更新睡眠异常",e);
            }
            oldPayTran = transactionPayTransactionMapper.getByOrderNo(getTransTableIndex(userBaseId), klksPayTransaction.getOrderNo());
            if (Objects.isNull(oldPayTran)) {
                KLog.warn("[交易-考拉快收-数据同步]交易更新,未获取到原交易,执行插入操作,入参:{}", dto.toJSON());
                payTransactionInsert(dto);
                return;
            }
//            KLog.error("[交易-考拉快收-数据同步]交易更新,未获取到原交易,入参:{}", dto.toJSON());
//            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到原交易");
        }

        PayTransaction upTra = fmtPayTransactionData(klksPayTransaction, userBaseId);

        if(oldPayTran.getStatus().equals(PayTransactionStatusEnum.STATUS_10.getCode()) || oldPayTran.getStatus().equals(PayTransactionStatusEnum.STATUS_20.getCode())){
            if(upTra.getStatus().equals(PayTransactionStatusEnum.STATUS_40.getCode())){
                KLog.warn("[交易-考拉快收-数据同步]交易更新,数据已为最终状态,不操作,入参:{}", dto.toJSON());
                return;
            }
        }

        upTra.setPayTransactionId(oldPayTran.getPayTransactionId());
        int upCount = transactionPayTransactionMapper.updateByIdNoVersion(getTransTableIndex(userBaseId), upTra);
        BizAssertUtils.assertOne(upCount, "更新交易失败");

        // 判断 如果是扣减交易额的交易，把分润状态再设置为0
        if (StringUtils.contains(oldPayTran.getRemarks(), SUBTRACT_TRANS_FLAG)) {
            upTra.setProfitFlag(Boolean.FALSE);
            KLog.info("[交易-考拉快收-数据同步] - [payTransactionUpdate] 扣减交易，不算分润，orderNo={}", upTra.getOrderNo());
        }

        try {
            //查询主表交易 卡类型不一致则更新为当前子表的卡类型
            PayTransactionIndexExample oldIndexExample = new PayTransactionIndexExample();
            oldIndexExample.createCriteria()
                    .andOrderNoEqualTo(upTra.getOrderNo());
            List<PayTransactionIndex> oldIndexList = payTransactionIndexMapper.selectByExample(oldIndexExample);
            if (CollectionUtils.isNotEmpty(oldIndexList) && Objects.nonNull(oldIndexList.get(0))) {
                PayTransactionIndex oldIndex = oldIndexList.get(0);
                if (!StringUtils.equals(upTra.getCardFlag(), oldIndex.getCardFlag())) {
                    log.info("主表和子表卡类型不一致,更新主表卡类型:{}", oldIndex.toString());
                    PayTransactionIndex payTransactionIndexUp = new PayTransactionIndex();
                    payTransactionIndexUp.setPayTransactionIndexId(oldIndex.getPayTransactionIndexId());
                    payTransactionIndexUp.setCardFlag(upTra.getCardFlag());
                    payTransactionIndexMapper.updateByPrimaryKeySelective(payTransactionIndexUp);
                }
            }
        } catch (Exception e) {
            KLog.error("主表和子表卡类型对比更新失败:{}",upTra.getOrderNo());
        }


        //电签交易且计入分润发送分润mq
        if (acmTransactionParams.getProfitMqFlag()
                && !oldPayTran.getProfitFlag()
                && upTra.getProfitFlag()
                && (ChannelIdEnums.epos.isEquals(upTra.getChannelId())
                    || ChannelIdEnums.epos_p30.isEquals(upTra.getChannelId())
                    || ChannelIdEnums.p35.isEquals(upTra.getChannelId()))) {
            tradeService.sendProfitPayTransactionMq(upTra);
        }
    }

    /**
     * 交易删除
     */
    private void payTransactionDelete(MigrateDTO dto){
        KLog.error("[交易-考拉快收-数据同步]交易删除,不支持的数据操作,入参:{}", dto.toJSON());
        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
    }

    /**
     * 格式化 交易数据
     */
    @Override
    public PayTransaction fmtPayTransactionData(KlksPayTransactionPO klksPayTransaction, String userBaseId){
        PayTransaction payTransaction = new PayTransaction();
        payTransaction.setUserBaseId(userBaseId);
        Merchant20 merchant20 = getMerchant20(merchant20Mapper, userBaseId, ChannelIdEnums.convertKuaiShouProductType(klksPayTransaction.getProductType()).getCode(), redis);

        payTransaction.setMerchantId(merchant20==null?null:merchant20.getMerchantId());
        payTransaction.setMerchantNo(klksPayTransaction.getMerNo());
        payTransaction.setMerchantName(klksPayTransaction.getMerName());
        payTransaction.setPhone(merchant20==null?null:merchant20.getPhone());
        payTransaction.setRealName(merchant20==null?null:merchant20.getRealName());
        payTransaction.setOrderNo(klksPayTransaction.getOrderNo());
        payTransaction.setTransactionNo(klksPayTransaction.getTransactionNo());
        payTransaction.setSysRef(klksPayTransaction.getSysRef());
        payTransaction.setSid(klksPayTransaction.getSid());
        payTransaction.setRevokeSid(klksPayTransaction.getRevokeSid());
        payTransaction.setTransactionAmount(klksPayTransaction.getTransAmt());
        payTransaction.setRate(klksPayTransaction.getRate());
        payTransaction.setTransactionFee(klksPayTransaction.getTransFee());
        payTransaction.setCardFlag(klksPayTransaction.getCardFlag());
        payTransaction.setTerminalId(klksPayTransaction.getTermId());
        payTransaction.setTransactionCardNo(klksPayTransaction.getTransCardNo());
        payTransaction.setTransactionBank(klksPayTransaction.getTransBank());
        payTransaction.setTransactionCardType(klksPayTransaction.getTransCardType());
        payTransaction.setSettlementCardNo(klksPayTransaction.getSettlementCardNo());
        payTransaction.setSettlementBank(klksPayTransaction.getSettlementBank());
        payTransaction.setSettlementCardType(klksPayTransaction.getSettlementCardType());
        payTransaction.setStatus(fmtPayTransactionStatus(klksPayTransaction.getStatus()));
        payTransaction.setTransactionTime(klksPayTransaction.getTransTime());
        payTransaction.setTransactionMonth(klksPayTransaction.getTransMonth());
        payTransaction.setTransactionDay(klksPayTransaction.getTransDay());
        if(StringUtils.isNotBlank(klksPayTransaction.getTransMonth())
            && StringUtils.isNotBlank(klksPayTransaction.getTransDay())) {
            payTransaction.setTransactionDay(klksPayTransaction.getTransMonth()+klksPayTransaction.getTransDay());
        }
        payTransaction.setFrontSuccessTime(klksPayTransaction.getAppSuccTime());
        payTransaction.setProvinceCode(klksPayTransaction.getProvinceCode());
        payTransaction.setCityCode(klksPayTransaction.getCityCode());
        payTransaction.setDistrictCode(klksPayTransaction.getDistrictCode());
        payTransaction.setAreaCode(klksPayTransaction.getAreaCode());
        payTransaction.setVersion(klksPayTransaction.getVersion());
        payTransaction.setChannelId(ChannelIdEnums.convertKuaiShouProductType(klksPayTransaction.getProductType()).getCode());
        payTransaction.setProfitFlag(getProfitFlag(klksPayTransaction,payTransaction.getChannelId()));
        payTransaction.setPlatNo(PlatNoEnums.KLKS.getCode());
        payTransaction.setIsDel(false);
        payTransaction.setCreateTime(klksPayTransaction.getCreateTime());
        payTransaction.setUpdateTime(klksPayTransaction.getUpdateTime() == null ? LocalDateTime.now()
                :klksPayTransaction.getUpdateTime());
        payTransaction.setRemarks(klksPayTransaction.getRemarks());
        payTransaction.setTransType(klksPayTransaction.getTransType());

        //支付成功
        if (payTransaction.getStatus() != null && PayTransactionStatusEnum.STATUS_10.getCode().equals(payTransaction.getStatus())) {
            if (ChannelIdEnums.mpos.isEquals(payTransaction.getChannelId())
                    || ChannelIdEnums.mpos_sdk.isEquals(payTransaction.getChannelId())) {
                payTransaction.setSn(payTransaction.getTerminalId());
            }
            if (ChannelIdEnums.epos.isEquals(payTransaction.getChannelId())
                    || ChannelIdEnums.epos_p30.isEquals(payTransaction.getChannelId())
                    || ChannelIdEnums.p35.isEquals(payTransaction.getChannelId())) {
                payTransaction.setSn(payTransaction.getRevokeSid());
            }
        }
        return payTransaction;
    }

    /**
     * 是否计入分润
     */
    private Boolean getProfitFlag(KlksPayTransactionPO klksPayTransaction,Short channelId){
        if(StringUtils.isBlank(klksPayTransaction.getCardFlag())){
            KLog.warn("快收获取到的cardFlag为空,TransactionNo:{}",klksPayTransaction.getTransactionNo());
            return false;
        }

        if (!StringUtils.equals(klksPayTransaction.getStatus(), KlksPayTransactionPO.STATUS_SUCC)) {
            return false;
        }

        //押金交易不计入分润
        if(StringUtils.equals(klksPayTransaction.getTransType(), "412001")){
            return false;
        }

        //贷记卡 微信 支付宝 纪录日统计
        if((ChannelIdEnums.epos.isEquals(channelId)
                ||ChannelIdEnums.epos_p30.isEquals(channelId)
                || ChannelIdEnums.p35.isEquals(channelId)
            )
            && StringUtils.equalsAnyIgnoreCase(klksPayTransaction.getCardFlag(),
                KlksPayTransactionPO.CARDFLAG_C, KlksPayTransactionPO.CARDFLAG_WECHAT,
                KlksPayTransactionPO.CARDFLAG_ALIPAY, KlksPayTransactionPO.CARDFLAG_82)
            ){
            return true;
        }
        return false;
    }

    private Boolean getPayWithdrawProfitFlag(PayTransaction payTransaction){
        //产品类型为蓝牙或蓝牙扫码 且 提款状态为成功
        if ((payTransaction.getChannelId().equals(ChannelIdEnums.mpos.getCode()) ||
                payTransaction.getChannelId().equals(ChannelIdEnums.mpos_qr.getCode())) &&
        payTransaction.getWithdrawalStatus().equals(PayTransactionWithdrawalStatusEnum.STATUS_50.getCode())){
            return true;
        }

        return false;

    }

    /**
     * 格式化交易状态
     */
    private Short fmtPayTransactionStatus(String klksStatus){
        if(StringUtils.isBlank(klksStatus)){
            return null;
        }
        if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_INIT)){
            return PayTransactionStatusEnum.STATUS_0.getCode();
        }else if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_SUCC)){
            return PayTransactionStatusEnum.STATUS_10.getCode();
        }else if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_FAIL)){
            return PayTransactionStatusEnum.STATUS_20.getCode();
        }else if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_REVOKE)){
            return PayTransactionStatusEnum.STATUS_32.getCode();
        }else if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_REVOKE_ING)){
            return PayTransactionStatusEnum.STATUS_31.getCode();
        }else if(StringUtils.equals(klksStatus, KlksPayTransactionPO.STATUS_APP_SUCC)){
            return PayTransactionStatusEnum.STATUS_40.getCode();
        }else {
            KLog.error("[交易-考拉快收-数据同步]格式化交易状态,不支持的交易状态,入参:{}", klksStatus);
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的交易状态");
        }
    }

    /**
     * 交易索引
     */
    @Override
    public void payTransactionIndex(MigrateDTO dto) {
        if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_INSERT)){
            payTransactionIndexInsert(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_UPDATE)){
            payTransactionIndexUpdate(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_DELETE)){
            payTransactionIndexDelete(dto);
        }else {
            KLog.error("[交易-考拉快收-数据同步]交易索引,不支持的数据操作入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
        }
    }

    /**
     * 交易索引插入
     * 必须参数：UserId，ProductType
     */
    private void payTransactionIndexInsert(MigrateDTO dto){

        KlksPayTransactionIndex klksPayTransactionIndex = JSONObject.parseObject(dto.getData(), KlksPayTransactionIndex.class);
        if(klksPayTransactionIndex==null){
            KLog.error("[交易-考拉快收-数据同步]交易索引插入,数据解析空,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "数据解析空");
        }

        if (StringUtils.equals(klksPayTransactionIndex.getProductType(),"06")){
            return;
        }
        if (!Objects.isNull(klksPayTransactionIndex.getTransAmt())){
            if (klksPayTransactionIndex.getTransAmt().compareTo(new BigDecimal("99999999.00")) > 0){
                return;
            }
        }

        if(StringUtils.isAnyBlank(klksPayTransactionIndex.getUserId(), klksPayTransactionIndex.getProductType())){
            KLog.error("[交易-考拉快收-数据同步]交易索引插入,缺失必须参数,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "缺失必须参数");
        }

        String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransactionIndex.getUserId(),redis);
        if(StringUtils.isBlank(userBaseId)){
            KLog.error("[交易-考拉快收-数据同步]交易索引插入,未获取到凌云用户id,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
        }

        PayTransactionIndexExample oldIndexExample = new PayTransactionIndexExample();
        oldIndexExample.createCriteria()
                .andOrderNoEqualTo(klksPayTransactionIndex.getOrderNo());
        List<PayTransactionIndex> oldIndexList = payTransactionIndexMapper.selectByExample(oldIndexExample);
        if(!CollectionUtils.isEmpty(oldIndexList)){
            KLog.warn("[交易-考拉快收-数据同步]交易索引插入,已存在该数据数据,不作处理,入参:{}", dto.toJSON());
            return;
//            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "已存在该数据");
        }

        PayTransactionIndex payIndex = fmtPayTransactionIndexData(klksPayTransactionIndex, userBaseId);
        int inCount = payTransactionIndexMapper.insertSelective(payIndex);
        BizAssertUtils.assertOne(inCount, "添加交易索引失败");
    }

    /**
     * 交易索引更新
     * 必须参数：UserId，OrderNo，ProductType
     */
    private void payTransactionIndexUpdate(MigrateDTO dto){

        KlksPayTransactionIndex klksPayTransactionIndex = JSONObject.parseObject(dto.getData(), KlksPayTransactionIndex.class);
        if(klksPayTransactionIndex==null){
            KLog.error("[交易-考拉快收-数据同步]交易索引更新,数据解析空,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "数据解析空");
        }

        if (StringUtils.equals(klksPayTransactionIndex.getProductType(),"06")){
            return;
        }
        if (!Objects.isNull(klksPayTransactionIndex.getTransAmt())){
            if (klksPayTransactionIndex.getTransAmt().compareTo(new BigDecimal("99999999.00")) > 0){
                return;
            }
        }

        if(StringUtils.isAnyBlank(klksPayTransactionIndex.getUserId(), klksPayTransactionIndex.getOrderNo(), klksPayTransactionIndex.getProductType())){
            KLog.error("[交易-考拉快收-数据同步]交易索引更新,缺失必须参数,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "缺失必须参数");
        }

        String userBaseId = getUserBaseId(userBaseExtMapper, klksPayTransactionIndex.getUserId(), redis);
        if(StringUtils.isBlank(userBaseId)){
            KLog.error("[交易-考拉快收-数据同步]交易索引更新,未获取到凌云用户id,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
        }

        PayTransactionIndexExample oldIndexExample = new PayTransactionIndexExample();
        oldIndexExample.createCriteria()
                .andOrderNoEqualTo(klksPayTransactionIndex.getOrderNo());
        List<PayTransactionIndex> oldIndexList = payTransactionIndexMapper.selectByExample(oldIndexExample);
        if(CollectionUtils.isEmpty(oldIndexList)){
            KLog.warn("[交易-考拉快收-数据同步]交易索引更新,未找到原交易索引数据,执行插入操作,入参:{}", dto.toJSON());
            payTransactionIndexInsert(dto);
            return;
//            KLog.error("[交易-考拉快收-数据同步]交易索引更新,未找到原交易索引数据,入参:{}", dto.toJSON());
//            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未找到原交易索引数据");
        }
        PayTransactionIndex oldIndex = oldIndexList.get(0);
        if(oldIndex==null){
            KLog.error("[交易-考拉快收-数据同步]交易索引更新,未获取到原交易,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到原交易");
        }

        PayTransactionIndex upIndex = fmtPayTransactionIndexData(klksPayTransactionIndex, userBaseId);

        if(oldIndex.getStatus().equals(PayTransactionStatusEnum.STATUS_10.getCode()) || oldIndex.getStatus().equals(PayTransactionStatusEnum.STATUS_20.getCode())){
            if(upIndex.getStatus().equals(PayTransactionStatusEnum.STATUS_40.getCode())){
                KLog.warn("[交易-考拉快收-数据同步]交易索引更新,数据已为最终状态,不操作,入参:{}", dto.toJSON());
                return;
            }
        }

        upIndex.setPayTransactionIndexId(oldIndex.getPayTransactionIndexId());
        int upCount = payTransactionIndexMapper.updateByPrimaryKeySelective(upIndex);
        BizAssertUtils.assertOne(upCount, "更新交易索引失败");
    }

    /**
     * 交易索引删除
     */
    private void payTransactionIndexDelete(MigrateDTO dto){
        KLog.error("[交易-考拉快收-数据同步]交易索引删除,不支持的数据操作,入参:{}", dto.toJSON());
        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
    }

    /**
     * 格式化 交易索引数据
     */
    @Override
    public PayTransactionIndex fmtPayTransactionIndexData(KlksPayTransactionIndex klksIndex, String userBaseId){
        PayTransactionIndex payIndex = new PayTransactionIndex();
        payIndex.setOrderNo(klksIndex.getOrderNo());
        payIndex.setTransactionNo(klksIndex.getTransactionNo());
        payIndex.setTableIndex(getTransTableIndex(userBaseId));
        payIndex.setUserBaseId(userBaseId);

        Merchant20 merchant20 = getMerchant20(merchant20Mapper, userBaseId, ChannelIdEnums.convertKuaiShouProductType(klksIndex.getProductType()).getCode(), redis);

        payIndex.setMerchantId(merchant20==null?null:merchant20.getMerchantId());
        payIndex.setMerchantNo(klksIndex.getMerNo());
        payIndex.setTransactionAmount(klksIndex.getTransAmt());
        payIndex.setTransactionTime(klksIndex.getTransTime());
        payIndex.setTransactionMonth(klksIndex.getTransMonth());
        if(StringUtils.isNotBlank(payIndex.getTransactionMonth())
                && StringUtils.isNotBlank(klksIndex.getTransDay())) {
            payIndex.setTransactionDay(payIndex.getTransactionMonth()+klksIndex.getTransDay());
        }
        PayTransaction payTransaction = transactionPayTransactionMapper.getByOrderNo(payIndex.getTableIndex(), payIndex.getOrderNo());

        payIndex.setCardFlag(payTransaction==null?null:payTransaction.getCardFlag());
        payIndex.setStatus(fmtPayTransactionStatus(klksIndex.getStatus()));
        payIndex.setWithdrawalStatus(payTransaction==null?null:payTransaction.getWithdrawalStatus());
        payIndex.setChannelId(ChannelIdEnums.convertKuaiShouProductType(klksIndex.getProductType()).getCode());
        payIndex.setPlatNo(PlatNoEnums.KLKS.getCode());
        payIndex.setIsDel(false);
        payIndex.setCreateTime(klksIndex.getCreateTime());
        payIndex.setUpdateTime(klksIndex.getUpdateTime() == null ?
                LocalDateTime.now() : klksIndex.getUpdateTime());

        return payIndex;
    }

    /**
     * D0提款
     */
    @Override
    public void payWithdrawal(MigrateDTO dto) {
        if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_INSERT)){
            payWithdrawalInsert(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_UPDATE)){
            payWithdrawalUpdate(dto);
        }else if(StringUtils.equals(dto.getOpt(), MigrateDTO.OPT_DELETE)){
            payWithdrawalDelete(dto);
        }else {
            KLog.error("[交易-考拉快收-数据同步]D0提款,不支持的数据操作入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
        }
    }

    /**
     * D0提款插入
     * 必须参数：UserId，OrderNo，ProductType
     *
     * 因为同比D0提款对应交易在交易表时已插入，故只需更新，无需插入操作
     */
    private void payWithdrawalInsert(MigrateDTO dto){
        payWithdrawalUpdate(dto);
    }

    /**
     * 扣减交易额标记，存在PayWithdrawalPO的remark中，从快收通过MQ传到凌云，更新到pay_transaction的remark，并设置为不发放分润
     */
    private final String SUBTRACT_TRANS_FLAG = "subtractTrans";

    /**
     * D0提款更新
     * 必须参数：UserId，OrderNo，ProductType
     */
    private void payWithdrawalUpdate(MigrateDTO dto){
        PayWithdrawalPO payWithdrawal = JSONObject.parseObject(dto.getData(), PayWithdrawalPO.class);
        if(payWithdrawal==null){
            KLog.error("[交易-考拉快收-数据同步]D0提款更新,数据解析空,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "数据解析空");
        }

        if(StringUtils.isAnyBlank(payWithdrawal.getUserId(), payWithdrawal.getOrderNo())){
            KLog.error("[交易-考拉快收-数据同步]D0提款更新,缺失必须参数,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "缺失必须参数");
        }

        String userBaseId = getUserBaseId(userBaseExtMapper, payWithdrawal.getUserId(), redis);
        if(StringUtils.isBlank(userBaseId)){
            KLog.error("[交易-考拉快收-数据同步]D0提款更新,未获取到凌云用户id,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到凌云用户id");
        }

        PayTransaction oldPayTran = transactionPayTransactionMapper.getByOrderNo(getTransTableIndex(userBaseId), payWithdrawal.getOrderNo());
        if(oldPayTran==null){
            KLog.error("[交易-考拉快收-数据同步]D0提款更新,未获取到原交易,入参:{}", dto.toJSON());
            throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "未获取到原交易");
        }

        PayTransaction upTra = fmtWithdrawalData(payWithdrawal);
        upTra.setPayTransactionId(oldPayTran.getPayTransactionId());
        oldPayTran.setWithdrawalStatus(upTra.getWithdrawalStatus());
        // 如果是扣减交易，分润标记改为为false
        if (StringUtils.equalsIgnoreCase(payWithdrawal.getRemark(), SUBTRACT_TRANS_FLAG)) {
            upTra.setProfitFlag(Boolean.FALSE);
            upTra.setRemarks(StringUtils.joinWith(", ", SUBTRACT_TRANS_FLAG, oldPayTran.getRemarks()));
            KLog.info("[交易-考拉快收-数据同步] - [payWithdrawalUpdate] 扣减交易，不算分润，orderNo={}", payWithdrawal.getOrderNo());
        } else {
            upTra.setProfitFlag(getPayWithdrawProfitFlag(oldPayTran));
        }
        int upCount = transactionPayTransactionMapper.updateByIdNoVersion(getTransTableIndex(userBaseId), upTra);

        BizAssertUtils.assertOne(upCount, "更新D0提款失败");

        if (acmTransactionParams.getProfitMqFlag() && upTra.getProfitFlag()){
            tradeService.sendProfitPayTransactionMq(oldPayTran);
        }
        if(upTra.getWithdrawalStatus() != null){
            PayTransactionIndexExample oldIndexExample = new PayTransactionIndexExample();
            oldIndexExample.createCriteria()
                    .andOrderNoEqualTo(payWithdrawal.getOrderNo());
            List<PayTransactionIndex> oldIndexList = payTransactionIndexMapper.selectByExample(oldIndexExample);
            if(CollectionUtils.isEmpty(oldIndexList)){
                KLog.warn("[交易-考拉快收-数据同步]D0提款更新,未找到原交易索引数据,入参:{}", dto.toJSON());
                return;
            }
            PayTransactionIndex oldIndex = oldIndexList.get(0);
            PayTransactionIndex upIndex = new PayTransactionIndex();
            upIndex.setPayTransactionIndexId(oldIndex.getPayTransactionIndexId());
            upIndex.setWithdrawalStatus(upTra.getWithdrawalStatus());
            int upIndexCount = payTransactionIndexMapper.updateByPrimaryKeySelective(upIndex);
            BizAssertUtils.assertOne(upIndexCount, "更新交易索引失败");
        }

    }

    /**
     * 格式化D0提款数据
     */
    @Override
    public PayTransaction fmtWithdrawalData(PayWithdrawalPO payWithdrawal) {
        PayTransaction upTra = new PayTransaction();
        upTra.setWithdrawalOrderNo(payWithdrawal.getSerialNo());
        upTra.setWithdrawalTransactionNo(payWithdrawal.getTranJnl());
        upTra.setWithdrawalAmount(payWithdrawal.getAmt());
        upTra.setWithdrawalFee(payWithdrawal.getFee());
        upTra.setFeeAmt(payWithdrawal.getFeeAmt());
        upTra.setAccAmt(payWithdrawal.getAccAmt());
        upTra.setWithdrawalQueryTime(payWithdrawal.getQueryTime());
        upTra.setWithdrawalQueryCount(payWithdrawal.getQueryCount());
        upTra.setWithdrawalDrawTime(payWithdrawal.getQueryDrawTime());
        upTra.setWithdrawalDrawCount(payWithdrawal.getQueryDrawCount());
        upTra.setWithdrawalStatus(getWithdrawStatus(payWithdrawal.getStatus()));
        return upTra;
    }

    /**
     * 格式化交易提款状态
     */
    private Short getWithdrawStatus(String klksStatus){
        if(StringUtils.isBlank(klksStatus)){
            return null;
        }
        if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_INIT)){
            return PayTransactionWithdrawalStatusEnum.STATUS_0.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_ING)){
            return PayTransactionWithdrawalStatusEnum.STATUS_10.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_SUCC)){
            return PayTransactionWithdrawalStatusEnum.STATUS_20.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_FAIL)){
            return PayTransactionWithdrawalStatusEnum.STATUS_30.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_NOT)){
            return PayTransactionWithdrawalStatusEnum.STATUS_40.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_ARRIVAL_SUCC)){
            return PayTransactionWithdrawalStatusEnum.STATUS_50.getCode();
        }else if(StringUtils.equals(klksStatus, PayWithdrawalPO.STATUS_ARRIVAL_FAIL)){
            return PayTransactionWithdrawalStatusEnum.STATUS_60.getCode();
        }
        KLog.error("[交易-考拉快收-数据同步]格式化交易提款状态,不支持的交易提款状态,入参:{}", klksStatus);
        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的交易状态");
    }

    /**
     * D0提款删除
     */
    private void payWithdrawalDelete(MigrateDTO dto){
        KLog.error("[交易-考拉快收-数据同步]D0提款删除,不支持的数据操作,入参:{}", dto.toJSON());
        throw new BizRuntimeException(BizCodeMessages.UNKNOWN_ERROR, "不支持的数据操作");
    }
}
